<template>
  <div>
    <div class="cropper-wrapper">
      <!-- element 上传图片按钮 -->
      <template>
          <!-- <el-upload class="upload-demo"
                      action=""
                      drag
                      :auto-upload="false"
                      :show-file-list="false"
                      :on-change='handleChangeUpload'>
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">点击上传</div>
              <div class="el-upload__tip">支持绝大多数图片格式，单张图片最大支持5MB</div>
          </el-upload> -->

          <el-upload :class="{ hideShow:hideUploadShow }" ref="upload" :headers="headers" :file-list='fileList' :disabled="disabled" list-type="picture-card"
            :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :limit="limit"

            :on-exceed="handleExceed"
            :action="action" 
            :auto-upload="false"
            :on-change='handleChangeUpload'>
            <i class="el-icon-plus"></i>
          </el-upload>
          <el-image-viewer  v-if="dialogViewVisible" :on-close="closeViewer" :initial-index="imageIndex" :url-list="urlList" />

          <!-- <el-upload :action="action" :headers="headers" :disabled="disabled" :file-list="fileList" list-type="picture-card"
            :on-preview="handlePictureCardPreview" :before-upload="handleBefore" :on-remove="handleRemove" :limit="limit"
            :on-error="handleSuccess" :on-success="handleSuccess">
            <i class="el-icon-plus"></i>
          </el-upload> -->
      </template>
      
      <!-- vueCropper 剪裁图片实现-->
      <el-dialog title="图片剪裁" top="15px" :width='dialogWidth' :visible.sync="dialogVisible" class="crop-dialog" append-to-body :close-on-click-modal="false" :close-on-press-escape="false" :before-close="handleClose">
          <div class="cropper-content">
              <div class="cropper" style="text-align:center">
                  <vueCropper
                      ref="cropper"
                      :img="option.img"
                      :outputSize="option.size"
                      :outputType="option.outputType"
                      :info="true"
                      :full="option.full"
                      :canMove="option.canMove"
                      :canMoveBox="option.canMoveBox"
                      :original="option.original"
                      :autoCrop="option.autoCrop"
                      :fixed="option.fixed"
                      :fixedNumber="option.fixedNumber"
                      :centerBox="option.centerBox"
                      :infoTrue="option.infoTrue"
                      :fixedBox="option.fixedBox"
                      :autoCropWidth="option.autoCropWidth"
                      :autoCropHeight="option.autoCropHeight"
                      @cropMoving="cropMoving"
                  />
              </div>
          </div>
          <div class="action-box">
              <!-- <el-upload class="upload-demo"
                          action=""
                          :auto-upload="false"
                          :show-file-list="false"
                          :on-change='handleChangeUpload'>
                  <el-button type="primary" plain>更换图片</el-button>
              </el-upload>
              <el-button type="primary" plain @click="clearImgHandle">清除图片</el-button> -->
              <el-button type="primary" plain @click="rotateLeftHandle">左旋转</el-button>
              <el-button type="primary" plain @click="rotateRightHandle">右旋转</el-button>
              <el-button type="primary" plain @click="changeScaleHandle(1)">放大</el-button>
              <el-button type="primary" plain @click="changeScaleHandle(-1)">缩小</el-button>
              <!-- <el-button type="primary" plain @click="downloadHandle('blob')">下载</el-button> -->
          </div>
          <div slot="footer" class="dialog-footer">
              <el-button @click="handleClose">取 消</el-button>
              <el-button type="primary" @click="finish" :loading="loading">确认</el-button>
          </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { BASEURL } from '../../../public/static/config'
import { getToken } from "@/utils/auth";
import request from '@/utils/request'
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
import Sortable from 'sortablejs';

export default {
  name: 'UploadImage',
  props: {
    imageList: {
      type: Array,
      default: () => []
    },
    image: {
      default: '',
      type: String
    },
    disabled: {
      default: false,
      type: Boolean
    },
		limit: {
		  default: 6,
		  type: Number
		},
    size: {
      default: 2,
      type: Number
    },
    type: {
      default: 1,
      type: Number
    },
  },
  components: {
    ElImageViewer
  },
  data() {
    return {
      action: (process.env.BASE_URL || BASEURL) + '/common/oss/single',
      fileList: [],
      dialogImageUrl: '',
      // dialogVisible: false,
      headers: {
        token: getToken()
      },
      urlList:[],
      imageIndex: 0,
      currentFile: {},
      dialogViewVisible: false,
      imageIndex: 0,
      dialogWidth: '400px',
      hideUploadShow: false,


      dialogVisible: false,
      previewImg: '', // 预览图片地址
      // 裁剪组件的基础配置option
      option: {
          img: '', // 裁剪图片的地址
          info: true, // 裁剪框的大小信息
          outputSize: 1, // 裁剪生成图片的质量
          outputType: 'png', // 裁剪生成图片的格式
          canScale: true, // 图片是否允许滚轮缩放
          autoCrop: true, // 是否默认生成截图框
          canMoveBox: true, // 截图框能否拖动
          autoCropWidth: 500, // 默认生成截图框宽度
          autoCropHeight: 500, // 默认生成截图框高度
          fixedBox: false, // 固定截图框大小 不允许改变
          fixed: true, // 是否开启截图框宽高固定比例
          fixedNumber: [1,1], // 截图框的宽高比例
          full: false, // 是否输出原图比例的截图
          original: false, // 上传图片按照原始比例渲染
          centerBox: false, // 截图框是否被限制在图片里面
          infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
          enlarge: 1,          //图片根据截图框输出比例倍数
          height: true,        //是否按照设备的dpr 输出等比例图片
      },
      // 防止重复提交
      loading: false
    }
  },
  computed: {},
  watch: {
    image: {
      immediate: true,
      handler(val) {
        if (val) {
          let item = {url: ''}
          item.url = val
          let array = []
          array.push(item)
          this.fileList = array
          
          if (this.fileList && this.fileList.length > 0 && this.fileList.length >= this.limit) {
            this.hideUploadShow = true
          } else {
            this.hideUploadShow = false
          }
        }
      }
    },
    imageList: {
      immediate: true,
      handler(val) {
        if (val && val.length > 0) {
          let array = []
          for (let index = 0; index < val.length; index++) {
            let element = val[index];
            let item = {}
            item.url = element
            array.push(item)
          }
          this.fileList = array

          if (this.fileList && this.fileList.length > 0 && this.fileList.length >= this.limit) {
            this.hideUploadShow = true
          } else {
            this.hideUploadShow = false
          }
        }
      }
    },
  },
  methods: {
    // 上传按钮 限制图片大小和类型
    handleChangeUpload(file, fileList) {
      if (file.status === 'success') {
        return
      }

      this.currentFile = file
      
      if (this.size > 0) {
        const fileSize = file.size / 1024 / 1024 < this.size
        if (!fileSize) {
          this.$message.error('文件大小不能超过' + this.size + 'MB')
          this.removeFile()
          return false
        }
      }
      if (['image/jpeg', 'image/png', 'image/bmp'].indexOf(
        file.raw.type
      ) === -1
      ) {
        this.$message.error('上传图片必须是JPG/PNG/BMP 格式')
        this.removeFile()
        return false
      }

      // 上传成功后将图片地址赋值给裁剪框显示图片
      this.$nextTick(async () => {
          // base64方式
          // this.option.img = await fileByBase64(file.raw)

          var reader = new FileReader();
          reader.readAsDataURL(file.raw); // 一定要传入file格式  
          reader.onload = () => {
            // console.log("file 转 base64结果：" + reader.result);
            this.option.img = reader.result

            this.loading = false
            this.dialogVisible = true

            setTimeout(() => {
              this.updateSize()
            }, 350);
            
          };

          // this.option.img = URL.createObjectURL(file.raw)
      })
    },
    updateSize() {
      let trueHeight = this.$refs.cropper.trueHeight
      let trueWidth = this.$refs.cropper.trueWidth
      let scale = this.$refs.cropper.scale
      if (trueHeight == trueWidth) {
        if (trueWidth < 500) {
          let result = trueWidth * scale
          if (result > 500) {
          } else {
            this.changeScaleHandle(1)
            this.updateSize()
          }
        }
        return
      } else {
        if (trueHeight > trueWidth) {
          let result = trueWidth * scale
          if (result > 500) {
          } else {
            this.changeScaleHandle(1)
            this.updateSize()
          }
        } else {
          let result = trueHeight * scale
          if (result > 500) {
          } else {
            this.changeScaleHandle(1)
            this.updateSize()
          }
        }
      }
    },
    // 放大/缩小
    changeScaleHandle(num) {
        num = num || 1;
        this.$refs.cropper.changeScale(num);
    },
    // 左旋转
    rotateLeftHandle() {
        this.$refs.cropper.rotateLeft();
    },
    // 右旋转
    rotateRightHandle() {
        this.$refs.cropper.rotateRight();
    },
    // 下载
    downloadHandle(type) {
        let aLink = document.createElement('a')
        aLink.download = 'author-img'
        if (type === 'blob') {
            this.$refs.cropper.getCropBlob((data) => {
                aLink.href = URL.createObjectURL(data)
                aLink.click()
            })
        } else {
            this.$refs.cropper.getCropData((data) => {
                aLink.href = data;
                aLink.click()
            })
        }
    },
    // 清理图片
    clearImgHandle() {
        this.option.img = ''
    },
    // 截图框移动回调函数
    cropMoving(data) {
        // 截图框的左上角 x，y和右下角坐标x，y
        // let cropAxis = [data.axis.x1, data.axis.y1, data.axis.x2, data.axis.y2]
        // console.log(cropAxis)
    },
    finish() {
        // 获取截图的 blob 数据
        this.$refs.cropper.getCropBlob((blob) => {
          this.loading = true
          this.dialogVisible = false
          this.previewImg = URL.createObjectURL(blob)
          // this.isPreview = true
        
          
          this.currentFile.url = URL.createObjectURL(blob)
          this.submitUpload(blob)
        })
    },
    submitUpload(blob) {// 上传图片
      var formData = new FormData();
      formData.append("file",blob,this.currentFile.name);

      // 上传图片
      request({
        url: this.action,
        data: formData,
        method: 'post',
        headers:{'Content-Type': 'multipart/form-data'},
      }).then(res => { 
        for (let index = 0; index < this.$refs.upload.uploadFiles.length; index++) {
          let element = this.$refs.upload.uploadFiles[index];
          if (element.uid === this.currentFile.uid) {
            let response = {}
            response.code = 200
            response.ok = true
            response.result = res
            element.response = response
            element.percentage = 100
            element.status = 'success'
            element.url = res
            break
          }
        }
        this.updateImageList()
      }).catch(error => {
        console.log(error);
      })
    },


    handleClose() {
      this.removeFile()
      this.dialogVisible = false
    },
    removeFile() {
      if (this.$refs.upload.uploadFiles.length > 0) {
        for (let index = 0; index < this.$refs.upload.uploadFiles.length; index++) {
          const element = this.$refs.upload.uploadFiles[index];
          if (element.uid === this.currentFile.uid) {
            this.$refs.upload.uploadFiles.splice(index, 1)
            break
          }
        }
      }
    },





    handlePictureCardPreview(file) {
      this.handleUrlList()
      for (let index = 0; index < this.urlList.length; index++) {
        const url = this.urlList[index];
        if (file.url == url) {
          this.imageIndex = index
          break
        }
      }
      this.dialogViewVisible = true;
    },
    handleExceed(files, fileList) {
      this.$message.error(`当前限制只能选择 ${this.limit} 个文件`);
    },
    handleRemove(file, files) {
      // console.log(111,files);
      // console.log(222, this.$refs.upload.uploadFiles);
      this.handleUrlList(files)
      this.updateImageList()
      this.$emit('update:defaultImage', files)
    },
    closeViewer() {
      this.dialogViewVisible = false
    },
    handleUrlList() {
      if (this.$refs.upload.uploadFiles.length > 0) {
        let urlList = this.$refs.upload.uploadFiles.map(item => {
          return item.url
        })
        this.$set(this, 'urlList', urlList)
      }
    },
    updateImageList() {
      if (this.$refs.upload.uploadFiles.length > 0) {
        let imageList = this.$refs.upload.uploadFiles.map(item => {
          if (item.status == 'success') {
            return item.url
          }
        })
        if (this.limit === 1) {
          if (imageList && imageList.length > 0) {
            this.$emit('update:image', imageList[0])
            this.hideUploadShow = true
          }
        } else {
          if (imageList && imageList.length > 0 && imageList.length >= this.limit) {
            this.hideUploadShow = true
          }
          this.$emit('update:imageList', imageList)
        }
      } else {
        this.$emit('update:image', '')
        this.$emit('update:imageList', [])
        this.hideUploadShow = false
      }
    },
    initUI() {
      let fixedBox = false
      let fixedNumber = [1,1]
      let dialogWidth = 0
      let autoCropWidth = 0
      if (this.type === 1) {
        fixedNumber = [1,1]
        fixedBox = true
        dialogWidth = '700px'
        autoCropWidth = 500
      } else if (this.type === 2) {//店铺图 比例 6:1
        fixedNumber = [6,1]
        fixedBox = false
        dialogWidth = '1540px'
        autoCropWidth = 1500
      }
      this.$set(this.option, 'fixedNumber', fixedNumber)
      this.$set(this.option, 'fixedBox', fixedBox)
      this.$set(this.option, 'autoCropWidth', autoCropWidth)
      this.$set(this, 'dialogWidth', dialogWidth)
    }
  },
  created() {
    this.initUI()
  },
  mounted() {
    const el = this.$refs.upload.$el.querySelectorAll('.el-upload-list')[0];
    let that = this
    Sortable.create(el, {
         onEnd: ({ oldIndex, newIndex }) => {
          // 交换位置
          const arr = that.$refs.upload.uploadFiles;
          const page = arr[oldIndex];
          arr.splice(oldIndex, 1);
          arr.splice(newIndex, 0, page);
          that.updateImageList()
          
         }
       });     
  },
  beforeCreate() {},
  beforeMount() {},
  beforeUpdate() {},
  updated() {},
  beforeDestroy() {},
  destroyed() {},
  activated() {},
}
</script>

<style lang='scss' scoped>
  .hideShow {
    ::v-deep .el-upload--picture-card {
      display: none;
    }
  }

  .cropper-wrapper {
    //height: calc(100vh - 50px);
    display: flex;
    justify-content: center;
    align-items: center;
    // transform: translate(-50px, -80px);
    .pre-box {
        display: flex;
        flex-direction: column;
        align-items: center;
        button {
            width: 100px;
            margin-top: 15px;
        }
    }
}

.crop-dialog {
    .cropper-content {
        // padding: 0 40px;
        width: 100%;

        .cropper {
            width: 100%;
            height: 500px;
        }
    }

    .action-box {
        padding: 25px 40px 0 40px;
        display: flex;
        justify-content: center;

        button {
            width: 80px;
            margin-right: 15px;
        }
    }

    .dialog-footer {
        button {
            width: 100px;
        }
    }
}
</style>